package com.example.zookeeper.config.zookeeper;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * zookeeper客户端配置
 */
public class ZkCuratorClient {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * zookeeper客户端实例
     */
    private CuratorFramework client;
    /**
     * 服务器列表，格式host1:port1,host2:port2,...
     */
    private String zookeeperServer;
    /**
     * 会话超时时间，单位毫秒，默认60000ms
     */
    private int sessionTimeoutMs;
    /**
     * 连接创建超时时间，单位毫秒，默认60000ms
     */
    private int connectionTimeoutMs;
    /**
     * 重试之间等待的初始时间
     */
    private int baseSleepTimeMs;
    /**
     * 当连接异常时的重试次数
     */
    private int maxRetries;
    /**
     * 为了实现不同的Zookeeper业务之间的隔离，有的时候需要为每个业务分配一个独立的命名空间
     */
    private String namespace;

    public void setZookeeperServer(String zookeeperServer) {
        this.zookeeperServer = zookeeperServer;
    }

    public void setSessionTimeoutMs(int sessionTimeoutMs) {
        this.sessionTimeoutMs = sessionTimeoutMs;
    }

    public void setConnectionTimeoutMs(int connectionTimeoutMs) {
        this.connectionTimeoutMs = connectionTimeoutMs;
    }
    public void setBaseSleepTimeMs(int baseSleepTimeMs) {
        this.baseSleepTimeMs = baseSleepTimeMs;
    }

    public void setMaxRetries(int maxRetries) {
        this.maxRetries = maxRetries;
    }

    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }

    /**
     * spring 自动调用,不需要我们主动调用
     */
    public void init() {
        // 创建客户端
        // 重连规则
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(baseSleepTimeMs, maxRetries);
        client = CuratorFrameworkFactory.builder()
                .connectString(zookeeperServer)
                .retryPolicy(retryPolicy)
                .sessionTimeoutMs(sessionTimeoutMs)
                .connectionTimeoutMs(connectionTimeoutMs)
                .namespace(namespace)
                .build();
        // 启动客户端,连接服务器
        client.start();
    }

    /**
     * spring 自动调用,不需要我们主动调用
     */
    public void stop() {
        // 关闭客户端
        client.close();
    }

    /**
     * 获取 zookeeper 客户端对象
     *
     * @return CuratorFramework
     */
    public CuratorFramework getClient() {
        return client;
    }
}
